#!/usr/bin/env lua

local fmt = string.format
package.path = package.path .. fmt(";%s/.config/river/?.lua", os.getenv("HOME"))

local river = require("river")

local noautorun = false
if arg[1] == "-n" then
    noautorun = true
end
local modifier = "Super"

local function mod(modi, key)
    if modi then
        return fmt("%s %s", modifier .. "+" .. modi, key)
    end
    return fmt("%s %s", modifier, key)
end

local function exec(cmds)
    for _, cmd in pairs(cmds) do
        os.execute(cmd)
    end
end

if not noautorun then
    exec({
        "dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=wlr",
    })

    for output, resolution in pairs(require("outputs")) do
        os.execute(
            fmt("wlr-randr --output %s --custom-mode %s", output, resolution)
        )
    end
end

river.maps("normal", {
    -- spawn something
    [mod("Shift", "Return")] = "spawn foot",
    [mod(nil, "R")] = "spawn \"bemenu-run -il6\"",
    -- [mod("Shift", "R")] = "spawn 'j4-dmenu-desktop --dmenu=\"bemenu -il 6\" --term=foot'",
    [mod("Shift", "R")] = "spawn fuzzel",
    [mod(nil, "Q")] = "close",
    [mod("Ctrl+Shift", "Q")] = "exit",
    [mod("Shift", "M")] = "spawn bemenu-loginmenu",
    [mod("Shift", "L")] = "spawn swaylock",
    [mod(nil, "P")] = "spawn bemenu-pass",
    [mod("Shift", "P")] = "spawn bemenu-pass otp",

    -- screenshots
    ["None Print"] = "spawn 'grim -c -g \"$(slurp -d)\" - | wl-copy -t image/png'",
    ["Shift Print"] = "spawn 'grim -c - | wl-copy -t image/png'",

    -- views
    [mod(nil, "J")] = "focus-view next",
    [mod(nil, "K")] = "focus-view previous",
    [mod(nil, "Return")] = "zoom",
    [mod("Shift", "J")] = "swap next",
    [mod("Shift", "K")] = "swap previous",
    [mod(nil, "Space")] = "toggle-float",
    [mod(nil, "F")] = "toggle-fullscreen",

    -- outputs
    [mod(nil, "Period")] = "focus-output next",
    [mod(nil, "Comma")] = "focus-output previous",
    [mod("Shift", "Period")] = "send-to-output next",
    [mod("Shift", "Comma")] = "send-to-output previous",

    -- movements
    [mod("Alt", "H")] = "move left 100",
    [mod("Alt", "J")] = "move down 100",
    [mod("Alt", "K")] = "move up 100",
    [mod("Alt", "L")] = "move right 100",
    [mod("Alt+Control", "H")] = "snap left",
    [mod("Alt+Control", "J")] = "snap down",
    [mod("Alt+Control", "K")] = "snap up",
    [mod("Alt+Control", "L")] = "snap right",
    [mod("Control", "H")] = "resize horizontal -100",
    [mod("Control", "J")] = "resize vertical 100",
    [mod("Control", "K")] = "resize vertical -100",
    [mod("Control", "L")] = "resize horizontal 100",

    -- etc
    [mod(nil, "H")] = "send-layout-cmd rivertile 'main-ratio -0.05'",
    [mod(nil, "L")] = "send-layout-cmd rivertile 'main-ratio +0.05'",
})

river.map_pointer("normal", mod(nil, "BTN_LEFT"), "move-view")
river.map_pointer("normal", mod(nil, "BTN_MIDDLE"), "toggle-float")
river.map_pointer("normal", mod(nil, "BTN_RIGHT"), "resize-view")

local function bitshift(x, n)
    for i = 1, n do
        x = x * 2
    end

    return x
end

for i = 1, 9 do
    local tags = bitshift(1, (i - 1))
    print(i, tags)

    river.maps("normal", {
        [mod(nil, tostring(i))] = fmt("set-focused-tags %d", tags),
        [mod("Shift ", tostring(i))] = fmt("set-view-tags %d", tags),
        [mod("Control ", tostring(i))] = fmt("toggle-focused-tags %d", tags),
        [mod("Shift+Control ", tostring(i))] = fmt("toggle-view-tags %d", tags),
    })
end

local all_tags = bitshift(1, 32) - 1

river.maps("normal", {
    [mod(nil, "0")] = "set-focused-tags " .. tostring(all_tags),
    [mod("Shift", "0")] = "set-view-tags " .. tostring(all_tags),
})

river.declare_mode("passthrough", {
    [mod(nil, "F11")] = "enter-mode normal",
})
river.map("normal", mod(nil, "F11"), "enter-mode passthrough")

for _, mode in pairs({ "normal", "locked" }) do
    river.maps(mode, {
        ["None XF86Eject"] = "spawn -T",

        ["None XF86AudioMedia"] = "spawn 'playerctl play-pause'",
        ["None XF86AudioPlay"] = "spawn 'playerctl play-pause'",
        ["None XF86AudioPrev"] = "spawn 'playerctl previous'",
        ["None XF86AudioNext"] = "spawn 'playerctl next'",
    })
end

river.appearance({
    background_color = "0x141414",

    border_color_focused = "0x349cc3",
    border_color_unfocused = "0x1f1f1f",
})

river.keyboard_layout("us,ru", "grp:caps_toggle")
river.repeat_rate(50, 300)

river.riverctl("set-cursor-warp on-focus-change")
river.riverctl("focus-follows-cursor normal")

for _, s in pairs({
    "mpv",
    "imv",
    "qemu",
    "xdg-desktop-portal-gtk",
    "org.keepassxc.KeePassXC",
    "swayimg",
}) do
    river.add_rule({ app_id = s }, "float")
end

for _, s in pairs({
    "xdg-desktop-portal-gtk",
    "virt-manager",
    "filezilla",
    "qemu",
    "imv",
    "tenacity",
    "im.dino.Dino",
    "LibreWolf",
    "gimp",
    "org.telegram.desktop",
    "librewolf"
}) do
    river.add_rule({ app_id = s }, "ssd")
end

river.layout("rivertile", "rivertile -view-padding 6 -outer-padding 4")

if not noautorun then
    exec({
        "waybar &",
        "swaybg -i ~/.local/share/wallpaper/wallpaper.jpg -m fill &",
        "mako &",
        "autostartctl boot &",
        "riverctl xcursor-theme Bibata-Original-Classic",
    })
end
